package com.xjk.excel;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFPalette;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbookFactory;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbookFactory;

/**
 * @author xjk
 * @date 2024-10-17
 */
public class ExcelWriterUtil <T>{


  public static final String XLSX = ".xlsx";
  public static final String XLS = ".xls";

  @ExcelTable(sheetName = "测试表",sheetType = SheetTypeEnum.XLS)
  static
  class TestA{

    @ExcelField(name = "姓名")
    @ExcelFiledStyle(
        fontSize = 12,
        bgColor = "#f00"
    )
    String name;

    @ExcelField(name = "年龄")
    @ExcelFiledStyle
    Integer age;

    @ExcelField(name = "生日")
    @ExcelFiledStyle(width = 24)
    Date date;

    @ExcelField(name = "生日2")
    @ExcelFiledStyle(width = 24)
    LocalDateTime localDateTime;

    @ExcelField(name = "余额")
    @ExcelFiledStyle
    BigDecimal money;

  }

  static
  class RandomNameGenerator {
    private static final String[] SURNAMES = {
        "李", "王", "张", "刘", "陈", "杨", "赵", "黄", "周", "吴",
        "徐", "孙", "马", "朱", "胡", "郭", "林", "何", "高", "罗"
    };

    private static final String[] FIRST_NAMES = {
        "伟", "芳", "娜", "敏", "静", "丽", "强", "磊", "军", "洋",
        "鹏", "杰", "涛", "明", "辉", "佳", "婷", "雪", "丽", "梅"
    };
    private static final String[] NAMES0 = {
        "伟", "芳", "娜", "敏", "静", "丽", "强", "磊", "军", "洋",
        "鹏", "杰", "涛", "明", "辉", "佳", "婷", "雪", "丽", "梅",
        "西", "东", "南", "北", "中", "上", "下", "左", "右", "前",
    };

    public static String generateRandomName() {
      Random random = new Random();

      // 随机选择一个姓和一个名
      String surname = SURNAMES[random.nextInt(SURNAMES.length)];
      String firstName = FIRST_NAMES[random.nextInt(FIRST_NAMES.length)];
      String n1 = NAMES0[random.nextInt(NAMES0.length)];

      return surname + firstName + n1;
    }
  }

  public static void main(String[] args) {


    List<TestA> dataList = new ArrayList<TestA>(){{
      Random random = new Random();
      for (int i = 0; i < 1000; i++) {
        TestA testA = new TestA();
        testA.age= random.nextInt(100);
        testA.name = RandomNameGenerator.generateRandomName();
        testA.date = new Date();
        testA.localDateTime = LocalDateTime.now();
        int cents = random.nextInt(100_0001);
        testA.money = BigDecimal.valueOf(cents,2);
        add(testA);
        System.out.println("创建" + i + "个对象");
      }
    }};

    createExcel("测试表", "D:\\Desktop", dataList,TestA.class);



  }

  public static void createExcel(String fileName,String filePath, List<?> dataList,Class<?> clazz){

    ExcelTable excelTable = clazz.getAnnotation(ExcelTable.class);
    String sheetName = excelTable.sheetName();
    SheetTypeEnum sheetTypeEnum = excelTable.sheetType();

    if (SheetTypeEnum.XLSX == sheetTypeEnum) {

      XSSFWorkbook workbook = XSSFWorkbookFactory.createWorkbook();

      XSSFSheet sheet = workbook.createSheet(sheetName);
      excelHeaderSettings(workbook, sheet, clazz);

      int i = 1;

      if (CollectionUtils.isNotEmpty(dataList)) {
        ExcelFiledStyle excelFiledStyle = clazz.getAnnotation(ExcelFiledStyle.class);
        XSSFCellStyle xssfCellStyle = preValueCreateCellStyle(workbook, excelFiledStyle);
        for (Object obj : dataList) {
          int index = dataList.indexOf(obj) + i;
          excelValueSetting(sheet, index, xssfCellStyle, obj);
          System.out.println("第" + index + "行写入完成");
        }
      }

      doWrite(fileName, filePath, workbook);

    }else if (SheetTypeEnum.XLS == sheetTypeEnum) {
      HSSFWorkbook workbook = HSSFWorkbookFactory.createWorkbook();

      HSSFSheet sheet = workbook.createSheet(sheetName);

      excelHeaderSettings(workbook, sheet, clazz);

      int i = 1;

      if (CollectionUtils.isNotEmpty(dataList)) {
        ExcelFiledStyle excelFiledStyle = clazz.getAnnotation(ExcelFiledStyle.class);
        HSSFCellStyle xssfCellStyle = preValueCreateCellStyle(workbook, excelFiledStyle);
        for (Object obj : dataList) {
          int index = dataList.indexOf(obj) + i;
          excelValueSetting(sheet, index, xssfCellStyle, obj);
          System.out.println("第" + index + "行写入完成");
        }
      }
      doWrite(fileName, filePath, workbook);
    }

  }

  private static void doWrite(String fileName, String filePath, XSSFWorkbook workbook) {
    try {
      Path path = Paths.get(filePath +System.getProperty("file.separator")+ fileName + XLSX);
      Files.createDirectories(path.getParent());
      try (OutputStream fileOut = new FileOutputStream(path.toFile())) {
        workbook.write(fileOut);
      }
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      try {
        workbook.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }

  private static void doWrite(String fileName, String filePath, HSSFWorkbook workbook) {
    try {
      Path path = Paths.get(filePath +System.getProperty("file.separator")+ fileName + XLS);
      Files.createDirectories(path.getParent());
      try (OutputStream fileOut = new FileOutputStream(path.toFile())) {
        workbook.write(fileOut);
      }
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      try {
        workbook.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }


  public static void excelHeaderSettings(XSSFWorkbook wb, XSSFSheet sheet, Class clazz){

    XSSFRow row = sheet.createRow(0);
    Field[] declaredFields = clazz.getDeclaredFields();
    for (int i = 0,cellIndex=0; i < declaredFields.length; i++,cellIndex++) {
      Field field = declaredFields[i];
      field.setAccessible(true);
      ExcelField annotation = field.getAnnotation(ExcelField.class);
      ExcelFiledStyle annotation1 = field.getAnnotation(ExcelFiledStyle.class);
      String name = Objects.isNull(annotation)?field.getName():annotation.name();
      if(Objects.nonNull(annotation)&&annotation.ignore()){
        cellIndex--;
        continue;
      }
      if(Objects.nonNull(annotation1)){
        sheet.setColumnWidth(cellIndex, annotation1.width()*256);
      }
      XSSFCellStyle xssfCellStyle = preHeadCreateCellStyle(wb,annotation1);
      createAllCell(row, cellIndex, xssfCellStyle, name);
    }

  }

  public static void excelHeaderSettings(HSSFWorkbook wb, HSSFSheet sheet, Class clazz){

    HSSFRow row = sheet.createRow(0);
    Field[] declaredFields = clazz.getDeclaredFields();
    for (int i = 0,cellIndex=0; i < declaredFields.length; i++,cellIndex++) {
      Field field = declaredFields[i];
      field.setAccessible(true);
      ExcelField annotation = field.getAnnotation(ExcelField.class);
      ExcelFiledStyle annotation1 = field.getAnnotation(ExcelFiledStyle.class);
      String name = Objects.isNull(annotation)?field.getName():annotation.name();
      if(Objects.nonNull(annotation)&&annotation.ignore()){
        cellIndex--;
        continue;
      }
      if(Objects.nonNull(annotation1)){
        sheet.setColumnWidth(cellIndex, annotation1.width()*256);
      }
      HSSFCellStyle xssfCellStyle = preHeadCreateCellStyle(wb,annotation1);
      createAllCell(row, cellIndex, xssfCellStyle, name);
    }

  }



  public static void excelValueSetting(XSSFSheet sheet,Integer rowIndex,XSSFCellStyle xssfCellStyle, Object obj){
    Class<?> clazz = obj.getClass();

    XSSFRow row = sheet.createRow(rowIndex);
    Field[] declaredFields = clazz.getDeclaredFields();
    for (int i = 0,cellIndex=0; i < declaredFields.length; i++,cellIndex++) {
      Field field = declaredFields[i];
      field.setAccessible(true);

      ExcelField annotation = field.getAnnotation(ExcelField.class);
      if(Objects.nonNull(annotation)&&annotation.ignore()){
        cellIndex--;
        continue;
      }

      Object value = null;
      try {
        if (field.getType() == BigDecimal.class) {
          value = ((BigDecimal)field.get(obj)).toPlainString();
        }else {
          value = field.get(obj);
        }
      } catch (IllegalAccessException e) {
        e.printStackTrace();
      }

      if (value == null) {
        value = "";
      }

      if (isDateType(field.getType())) {
        Date date = convertToDate(value);
        createAllCell(row,cellIndex,xssfCellStyle,date);
      }else {
        createAllCell(row,cellIndex,xssfCellStyle,value.toString());
      }
    }

  }

  public static void excelValueSetting(HSSFSheet sheet,Integer rowIndex,HSSFCellStyle cellStyle, Object obj){
    Class<?> clazz = obj.getClass();

    HSSFRow row = sheet.createRow(rowIndex);
    Field[] declaredFields = clazz.getDeclaredFields();
    for (int i = 0,cellIndex=0; i < declaredFields.length; i++,cellIndex++) {
      Field field = declaredFields[i];
      field.setAccessible(true);

      ExcelField annotation = field.getAnnotation(ExcelField.class);
      if(Objects.nonNull(annotation)&&annotation.ignore()){
        cellIndex--;
        continue;
      }

      Object value = null;
      try {
        if (field.getType() == BigDecimal.class) {
          value = ((BigDecimal)field.get(obj)).toPlainString();
        }else {
          value = field.get(obj);
        }
      } catch (IllegalAccessException e) {
        e.printStackTrace();
      }

      if (value == null) {
        value = "";
      }

      if (isDateType(field.getType())) {
        Date date = convertToDate(value);
        createAllCell(row,cellIndex,cellStyle,date);
      }else {
        createAllCell(row,cellIndex,cellStyle,value.toString());
      }
    }

  }



  private static XSSFCellStyle preHeadCreateCellStyle(XSSFWorkbook wb, ExcelFiledStyle filedStyle) {
    XSSFCellStyle cellStyle = wb.createCellStyle();

    String bC = "#000000";
    String bgC = "#ffffff";
    String fC = "#000000";
    String dateFormat = "yyyy-MM-dd HH:mm:ss";
    HorizontalAlignment xAlign = HorizontalAlignment.CENTER;
    VerticalAlignment yAlign = VerticalAlignment.CENTER;
    BorderStyle borderStyle = BorderStyle.NONE;
    String fontFamily = "微软雅黑";
    short fontSize = 12;

    if (Objects.nonNull(filedStyle)){
      bC = filedStyle.borderColor();
      fC = filedStyle.fontColor();
      bgC = filedStyle.bgColor();
      dateFormat = filedStyle.dateFormat();
      xAlign = TextAlignmentEnum.xMap.get(filedStyle.alignHorizontal());
      yAlign = TextAlignmentEnum.yMap.get(filedStyle.alignVertically());
      borderStyle = BorderStyleEnum.borderStyleMap.get(filedStyle.borderStyle());
      fontFamily = filedStyle.fontFamily();
      fontSize = filedStyle.fontSize();
    }

    XSSFColor borderColor = new XSSFColor(hexToRgb(bC), null);
    XSSFColor bgColor = new XSSFColor(hexToRgb(bgC), null);
    XSSFColor fontColor = new XSSFColor(hexToRgb(fC), null);
    cellStyle.setAlignment(xAlign);
    cellStyle.setVerticalAlignment(yAlign);
    cellStyle.setBorderBottom(borderStyle);
    cellStyle.setBottomBorderColor(borderColor.getIndex());
    cellStyle.setBorderLeft(borderStyle);
    cellStyle.setLeftBorderColor(borderColor.getIndex());
    cellStyle.setBorderRight(borderStyle);
    cellStyle.setRightBorderColor(borderColor.getIndex());
    cellStyle.setBorderTop(borderStyle);
    cellStyle.setTopBorderColor(borderColor.getIndex());
    cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
    cellStyle.setDataFormat(wb.getCreationHelper().createDataFormat().getFormat(dateFormat));
    cellStyle.setFillForegroundColor(bgColor);
    XSSFFont font = wb.createFont();
    font.setFontName(fontFamily);
    font.setFontHeightInPoints(fontSize);
    font.setColor(fontColor);
    cellStyle.setFont(font);
    return cellStyle;

  }

  private static HSSFCellStyle preHeadCreateCellStyle(HSSFWorkbook wb, ExcelFiledStyle filedStyle) {
    HSSFCellStyle cellStyle = wb.createCellStyle();

    String bC = "#000000";
    String bgC = "#ffffff";
    String fC = "#000000";
    String dateFormat = "yyyy-MM-dd HH:mm:ss";
    HorizontalAlignment xAlign = HorizontalAlignment.CENTER;
    VerticalAlignment yAlign = VerticalAlignment.CENTER;
    BorderStyle borderStyle = BorderStyle.NONE;
    String fontFamily = "微软雅黑";
    short fontSize = 12;

    if (Objects.nonNull(filedStyle)){
      bC = filedStyle.borderColor();
      fC = filedStyle.fontColor();
      bgC = filedStyle.bgColor();
      dateFormat = filedStyle.dateFormat();
      xAlign = TextAlignmentEnum.xMap.get(filedStyle.alignHorizontal());
      yAlign = TextAlignmentEnum.yMap.get(filedStyle.alignVertically());
      borderStyle = BorderStyleEnum.borderStyleMap.get(filedStyle.borderStyle());
      fontFamily = filedStyle.fontFamily();
      fontSize = filedStyle.fontSize();
    }

    HSSFPalette palette = wb.getCustomPalette();



    HSSFColor borderColor = doHSSFColor(bC, palette);
    HSSFColor bgColor = doHSSFColor(bgC, palette);
    HSSFColor fontColor = doHSSFColor(fC, palette);
    cellStyle.setAlignment(xAlign);
    cellStyle.setVerticalAlignment(yAlign);
    cellStyle.setBorderBottom(borderStyle);
    cellStyle.setBottomBorderColor(borderColor.getIndex());
    cellStyle.setBorderLeft(borderStyle);
    cellStyle.setLeftBorderColor(borderColor.getIndex());
    cellStyle.setBorderRight(borderStyle);
    cellStyle.setRightBorderColor(borderColor.getIndex());
    cellStyle.setBorderTop(borderStyle);
    cellStyle.setTopBorderColor(borderColor.getIndex());
    cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
    cellStyle.setDataFormat(wb.getCreationHelper().createDataFormat().getFormat(dateFormat));
    cellStyle.setFillForegroundColor(bgColor.getIndex());
    HSSFFont font = wb.createFont();
    font.setFontName(fontFamily);
    font.setFontHeightInPoints(fontSize);
    font.setColor(fontColor.getIndex());
    cellStyle.setFont(font);
    return cellStyle;

  }

  private static HSSFColor doHSSFColor(String bC, HSSFPalette palette) {
    HSSFColor hssfColor = palette.findColor(hexToRgb(bC)[0],  hexToRgb(bC)[1],  hexToRgb(bC)[2]);
    if (hssfColor == null) {
      palette.setColorAtIndex(HSSFColor.HSSFColorPredefined.LAVENDER.getIndex(), hexToRgb(bC)[0],  hexToRgb(bC)[1],  hexToRgb(bC)[2]);
      hssfColor = palette.findColor(hexToRgb(bC)[0],  hexToRgb(bC)[1],  hexToRgb(bC)[2]);
    }
    return hssfColor;
  }


  private static XSSFCellStyle preValueCreateCellStyle(XSSFWorkbook wb, ExcelFiledStyle filedStyle) {
    XSSFCellStyle cellStyle = wb.createCellStyle();

    String bC = "#000000";
    String bgC = "#ffffff";
    String fC = "#000000";
    String dateFormat = "yyyy-MM-dd HH:mm:ss";
    HorizontalAlignment xAlign = HorizontalAlignment.CENTER;
    VerticalAlignment yAlign = VerticalAlignment.CENTER;
    BorderStyle borderStyle = BorderStyle.THIN;
    String fontFamily = "微软雅黑";
    short fontSize = 12;

    if (Objects.nonNull(filedStyle)){
      bC = filedStyle.borderColor();
      fC = filedStyle.fontColor();
      bgC = filedStyle.bgColor();
      dateFormat = filedStyle.dateFormat();
      xAlign = TextAlignmentEnum.xMap.get(filedStyle.alignHorizontal());
      yAlign = TextAlignmentEnum.yMap.get(filedStyle.alignVertically());
      borderStyle = BorderStyleEnum.borderStyleMap.get(filedStyle.borderStyle());
      fontFamily = filedStyle.fontFamily();
      fontSize = filedStyle.fontSize();
    }

    XSSFColor borderColor = new XSSFColor(hexToRgb(bC), null);
    XSSFColor bgColor = new XSSFColor(hexToRgb(bgC), null);
    XSSFColor fontColor = new XSSFColor(hexToRgb(fC), null);
    cellStyle.setAlignment(xAlign);
    cellStyle.setVerticalAlignment(yAlign);
    cellStyle.setBorderBottom(borderStyle);
    cellStyle.setBottomBorderColor(borderColor.getIndex());
    cellStyle.setBorderLeft(borderStyle);
    cellStyle.setLeftBorderColor(borderColor.getIndex());
    cellStyle.setBorderRight(borderStyle);
    cellStyle.setRightBorderColor(borderColor.getIndex());
    cellStyle.setBorderTop(borderStyle);
    cellStyle.setTopBorderColor(borderColor.getIndex());
    cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
    cellStyle.setDataFormat(wb.getCreationHelper().createDataFormat().getFormat(dateFormat));
    cellStyle.setFillForegroundColor(bgColor);
    XSSFFont font = wb.createFont();
    font.setFontName(fontFamily);
    font.setFontHeightInPoints(fontSize);
    font.setColor(fontColor);
    cellStyle.setFont(font);
    return cellStyle;

  }

  private static HSSFCellStyle preValueCreateCellStyle(HSSFWorkbook wb, ExcelFiledStyle filedStyle) {
    HSSFCellStyle cellStyle = wb.createCellStyle();

    String bC = "#000000";
    String bgC = "#ffffff";
    String fC = "#000000";
    String dateFormat = "yyyy-MM-dd HH:mm:ss";
    HorizontalAlignment xAlign = HorizontalAlignment.CENTER;
    VerticalAlignment yAlign = VerticalAlignment.CENTER;
    BorderStyle borderStyle = BorderStyle.THIN;
    String fontFamily = "微软雅黑";
    short fontSize = 12;

    if (Objects.nonNull(filedStyle)){
      bC = filedStyle.borderColor();
      fC = filedStyle.fontColor();
      bgC = filedStyle.bgColor();
      dateFormat = filedStyle.dateFormat();
      xAlign = TextAlignmentEnum.xMap.get(filedStyle.alignHorizontal());
      yAlign = TextAlignmentEnum.yMap.get(filedStyle.alignVertically());
      borderStyle = BorderStyleEnum.borderStyleMap.get(filedStyle.borderStyle());
      fontFamily = filedStyle.fontFamily();
      fontSize = filedStyle.fontSize();
    }
    HSSFPalette palette = wb.getCustomPalette();

    HSSFColor borderColor = doHSSFColor(bC, palette);
    HSSFColor bgColor = doHSSFColor(bgC, palette);
    HSSFColor fontColor = doHSSFColor(fC, palette);
    cellStyle.setAlignment(xAlign);
    cellStyle.setVerticalAlignment(yAlign);
    cellStyle.setBorderBottom(borderStyle);
    cellStyle.setBottomBorderColor(borderColor.getIndex());
    cellStyle.setBorderLeft(borderStyle);
    cellStyle.setLeftBorderColor(borderColor.getIndex());
    cellStyle.setBorderRight(borderStyle);
    cellStyle.setRightBorderColor(borderColor.getIndex());
    cellStyle.setBorderTop(borderStyle);
    cellStyle.setTopBorderColor(borderColor.getIndex());
    cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
    cellStyle.setDataFormat(wb.getCreationHelper().createDataFormat().getFormat(dateFormat));
    cellStyle.setFillForegroundColor(bgColor.getIndex());
    HSSFFont font = wb.createFont();
    font.setFontName(fontFamily);
    font.setFontHeightInPoints(fontSize);
    font.setColor(fontColor.getIndex());
    cellStyle.setFont(font);
    return cellStyle;

  }

  private static void createAllCell(XSSFRow row, int column,
      XSSFCellStyle cellStyle,
      String value) {
    XSSFCell cell = row.createCell(column);
    cell.setCellValue(value);
    cell.setCellStyle(cellStyle);
  }

  private static void createAllCell(XSSFRow row, int column,
      XSSFCellStyle cellStyle,
      Date dateValue) {
    XSSFCell cell = row.createCell(column);
    cell.setCellValue(dateValue);
    cell.setCellStyle(cellStyle);
  }

  private static void createAllCell(HSSFRow row, int column,
      HSSFCellStyle cellStyle,
      String value) {
    HSSFCell cell = row.createCell(column);
    cell.setCellValue(value);
    cell.setCellStyle(cellStyle);
  }

  private static void createAllCell(HSSFRow row, int column,
      HSSFCellStyle cellStyle,
      Date dateValue) {
    HSSFCell cell = row.createCell(column);
    cell.setCellValue(dateValue);
    cell.setCellStyle(cellStyle);
  }


  private static byte[] hexToRgb(String hex) {
    // 去掉前导的 '#'，如果有的话
    hex = hex.replace("#", "");

    if (hex.length() == 3){
      hex = "" + hex.charAt(0) + hex.charAt(0)
          + hex.charAt(1) + hex.charAt(1)
          + hex.charAt(2) + hex.charAt(2);
    }

    // 将 HEX 转换为整数
    byte r = (byte) Integer.parseInt(hex.substring(0, 2), 16);
    byte g = (byte) Integer.parseInt(hex.substring(2, 4), 16);
    byte b = (byte) Integer.parseInt(hex.substring(4, 6), 16);
    return new byte[]{r, g, b};
  }

  private static int[] hexToRgbInt(String hex) {
    // 去掉前导的 '#'，如果有的话
    hex = hex.replace("#", "");

    if (hex.length() == 3){
      hex = "" + hex.charAt(0) + hex.charAt(0)
          + hex.charAt(1) + hex.charAt(1)
          + hex.charAt(2) + hex.charAt(2);
    }

    int red = Integer.parseInt(hex.substring(0, 2), 16);
    int green = Integer.parseInt(hex.substring(2, 4), 16);
    int blue = Integer.parseInt(hex.substring(4, 6), 16);

    return new int[]{red, green, blue};
  }


  private static boolean isDateType(Class<?> clazz) {
    return clazz.equals(Date.class) ||
        clazz.equals(LocalDate.class) ||
        clazz.equals(LocalDateTime.class) ||
        clazz.equals(Instant.class) ||
        clazz.equals(java.sql.Date.class) ||
        clazz.equals(java.sql.Timestamp.class);
  }

  private static Date convertToDate(Object value) {
    if (value instanceof Date) {
      return (Date) value;
    } else if (value instanceof LocalDate) {
      return Date.from(((LocalDate) value).atStartOfDay(ZoneId.systemDefault()).toInstant());
    } else if (value instanceof LocalDateTime) {
      return Date.from(((LocalDateTime) value).atZone(ZoneId.systemDefault()).toInstant());
    } else if (value instanceof Instant) {
      return Date.from((Instant) value);
    } else if (value instanceof java.sql.Date) {
      return new Date(((java.sql.Date) value).getTime());
    } else if (value instanceof java.sql.Timestamp) {
      return new Date(((java.sql.Timestamp) value).getTime());
    } else {
      throw new IllegalArgumentException("Unsupported date type: " + value.getClass());
    }
  }

}
